﻿
// <copyright file="AbstractCollectionDecorator.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The AbstractCollectionDecorator class.
// </summary>


namespace SubhadraSolutions.Sharp.Utils.Collections.Generic
{
    using System.Collections;
    using System.Collections.Generic;

    using SubhadraSolutions.Sharp.Utils.Validation;

    /// <summary>
    /// The AbstractCollectionDecorator class.
    /// </summary>
    /// <typeparam name="T">
    /// </typeparam>
    public abstract class AbstractCollectionDecorator<T> : ICollection<T>
    {
        /// <summary>
        /// The adapted object
        /// </summary>
        private readonly ICollection<T> adaptedCollection;

        /// <summary>
        /// Initializes a new instance of the <see cref="AbstractCollectionDecorator{T}"/> class.
        /// </summary>
        /// <param name="adaptedCollection">
        /// The adapted collection.
        /// </param>
        protected AbstractCollectionDecorator(ICollection<T> adaptedCollection)
        {
            Guard.ArgumentNotNull(adaptedCollection, "adaptedCollection");
            this.adaptedCollection = adaptedCollection;
        }

        /// <summary>
        /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1" />.
        /// </summary>
        public virtual int Count
        {
            get
            {
                return this.adaptedCollection.Count;
            }
        }

        /// <summary>
        /// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.
        /// </summary>
        public virtual bool IsReadOnly
        {
            get
            {
                return this.adaptedCollection.IsReadOnly;
            }
        }

        /// <summary>
        /// Gets the adapted object.
        /// </summary>
        /// <value>
        /// The adapted object.
        /// </value>
        protected ICollection<T> AdaptedCollection
        {
            get
            {
                return this.adaptedCollection;
            }
        }

        /// <summary>
        /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </summary>
        /// <param name="item">
        /// The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </param>
        /// <returns>
        /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </returns>
        public virtual bool Remove(T item)
        {
            return this.adaptedCollection.Remove(item);
        }

        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
        /// </returns>
        public virtual IEnumerator<T> GetEnumerator()
        {
            return this.adaptedCollection.GetEnumerator();
        }

        /// <summary>
        /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </summary>
        /// <param name="item">
        /// The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </param>
        public virtual void Add(T item)
        {
            this.adaptedCollection.Add(item);
        }

        /// <summary>
        /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1" />.
        /// </summary>
        public virtual void Clear()
        {
            this.adaptedCollection.Clear();
        }

        /// <summary>
        /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
        /// </summary>
        /// <param name="item">
        /// The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </param>
        /// <returns>
        /// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
        /// </returns>
        public virtual bool Contains(T item)
        {
            return this.adaptedCollection.Contains(item);
        }

        /// <summary>
        /// Copies to.
        /// </summary>
        /// <param name="array">
        /// The array.
        /// </param>
        /// <param name="arrayIndex">
        /// Index of the array.
        /// </param>
        public virtual void CopyTo(T[] array, int arrayIndex)
        {
            this.adaptedCollection.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
        /// </returns>
        IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.adaptedCollection.GetEnumerator();
        }
    }
}
